
import React from "react";
import * as THREE from 'three';
import Controller, { State } from "./Controller";

import useRenderer from "./hooks/useRenderer";
import useScene from "./hooks/useScene";
import useCamera from "./hooks/useCamera";
import useResize from "./hooks/useResize";
import useFloor from "./hooks/useFloor";
import useGridHelper from "./hooks/useGridHelper";
import useSelect from "./hooks/useSelect";
import useTransformControls from "./hooks/useTransformControls";
import useHotKey from "./hooks/useHotKey";
import useBox3Helper from "./hooks/useBox3Helper";
import useLightHelper from "./hooks/useLightHelper";
import useImportModel from "./hooks/useImportModel";
import useControls from "./hooks/useControls";

export { default as ThreeController } from "./Controller";
export { default as Element } from "./Controller/State/Element";

export interface IThreeProps {

    /** 控制器 */
    controller?: Controller;

    /** 舞台 */
    scene?: string | THREE.Scene;

    /** 样式 */
    className?: string;
}

export default class Three extends React.Component<IThreeProps>{

    /** 控制器 */
    static Controller = Controller;

    /** 状态 */
    static State = State;

    static Context = React.createContext<Controller>(null as any);

    render() {
        return <Main {...this.props} />
    }
}

function Main(props: IThreeProps) {

    const controller = React.useMemo(() => props.controller || new Controller(), [props.controller]);

    useScene(controller, props.scene); //      创建舞台
    useRenderer(controller); //                创建渲染器
    useCamera(controller); //                  摄像头
    useControls(controller); //                球形轨道
    useResize(controller); //                  窗口大小变化
    useFloor(controller); //                   设置地板
    useGridHelper(controller); //              网格
    useTransformControls(controller); //       原件控制器
    useHotKey(controller); //                  快捷键  
    useBox3Helper(controller); //              3维包围盒
    useLightHelper(controller); //             灯关辅助
    useSelect(controller); //                  选取工具
    useImportModel(controller); //             导入模型工具

    return (
        <Three.Context.Provider value={controller} >
            <div ref={controller.pipeline(async (s, e) => { s.cont = e })} className={props.className} />
        </Three.Context.Provider>
    )
}